package com.damionew.website.shiro;
/**
 * shiro从Relam获取安全数据（用户，角色，权限等）
 * SecurityManager要验证用户身份，需要从Realm获取相应的用户进行比较已确定用户身份是否合法
 * 也需要从Realm得到用户相应的角色/权限进行验证用户能否进行操作
 * 可视为DataSource即安全数据源
 * --摘抄自开涛博客
 */
import org.apache.shiro.SecurityUtils;
/**
 * @Author yinyunqi
 * @date 2017/12/6
 * @Content shiro登录验证
 */
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import com.damionew.website.model.back.Member;
import com.damionew.website.service.back.MemberService;

public class MyShiroRealm extends AuthorizingRealm {

	@Autowired
	MemberService memberService;
	//用户授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Member member = (Member) principals.getPrimaryPrincipal();
		String account = member.getAccount();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		//调用findRoles方法获取role角色
		authorizationInfo.setRoles(memberService.findRoles(account));
		authorizationInfo.setStringPermissions(memberService.findPermissions(account));
		return authorizationInfo;
	}

	// 登录验证
	@Override
	protected org.apache.shiro.authc.AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		// 通过表单获得的账户名
		String account = (String) authcToken.getPrincipal();
		// select password from member where account=#{account}
		// 获取一个Member类的member
		Member member = memberService.getMemberLogin(account);
		if (!StringUtils.isEmpty(member)) {
			if (member.getPassword() != null) {
				// 验证交给shiro
				// 三个参数为Member对象，从数据库获取的密码，当前Realm名称
				// 登录账户account相当于username，必然是相同的
				// 因为是从表单获得的account，然后拿来查询，比较的是从数据库获取得password和token中获得的password
				SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
					member,
					member.getPassword(), 
					ByteSource.Util.bytes(member.getAccount()),//加盐，用户account
					getName());
				return simpleAuthenticationInfo;
			}
		}
		return null;
	}

	// 清除缓存
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}
}
